﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.OleDb;

namespace QuanLyHocPhi.BLL.Excel
{
    public class ExcelImporter
    {
        #region Constructor
        public ExcelImporter(string importFileName)
        {
            this.m_FileName = importFileName;
        }
        #endregion

        #region Properties
        private string m_FileName;

        public string FileName
        {
            get { return m_FileName; }
            set { m_FileName = value; }
        }

        #endregion

        #region Method
        private OleDbConnection CreateConnection()
        {
            OleDbConnection cn = new OleDbConnection();
            try
            {
                //cn.ConnectionString = string.Format(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties='Excel 12.0 Xml;'", m_FileName);
                cn.ConnectionString = string.Format(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=Excel 8.0;", m_FileName);
                return cn;
            }
            catch (Exception ex)
            {
                //try
                //{
                //    cn.ConnectionString = string.Format(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=Excel 12.0 Xml;HDR=YES;", m_FileName);
                //    return cn;
                //}
                //catch
                //{
                //    throw ex;
                //}
                throw ex;
            }
        }

        private OleDbConnection CreateConnection(bool headerEnable)
        {
            try
            {
                OleDbConnection cn = new OleDbConnection();
                if (headerEnable)
                {
                    cn.ConnectionString = string.Format(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=""Excel 8.0;HDR=Yes""", m_FileName);
                }
                else
                {
                    cn.ConnectionString = string.Format(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=""Excel 8.0;HDR=No""", m_FileName);
                }
                return cn;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// Lấy danh sách các bảng và sheet trong file Excel
        /// </summary>
        /// <returns></returns>
        public List<string> GetTableList()
        {
            try
            {
                OleDbConnection cn = CreateConnection();
                cn.Open();
                DataTable dt = cn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables,
                                    new object[] { null, null, null, "Table" });
                cn.Close();
                List<string> list = new List<string>();
                foreach (DataRow dr in dt.Rows)
                {
                    list.Add(dr["TABLE_NAME"].ToString());
                }
                cn.Dispose();
                return list;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// Lấy danh sách các tiêu đề cột của một bảng hoặc một sheet trong file excel
        /// </summary>
        /// <param name="fileName">Tên file</param>
        /// <param name="tableName">Tên bảng hoặc tên sheet</param>
        /// <param name="headerEnable">Có sử dụng dòng đầu tiên làm dòng tiêu đề hay không?</param>
        /// <returns></returns>
        private List<string> ListOfColumns(string fileName, string tableName, bool headerEnable)
        {
            try
            {
                OleDbConnection cn = CreateConnection(headerEnable);
                cn.Open();
                DataTable dt = cn.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, new object[] { null, null, tableName });
                cn.Close();
                List<string> list = new List<string>();
                foreach (DataRow dr in dt.Rows)
                {
                    list.Add(dr["COLUMN_NAME"].ToString());
                }
                cn.Dispose();
                return list;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// Đọc dữ liệu từ một bảng hoặc sheet trong file excel
        /// </summary>
        /// <param name="fileName">Tên file</param>
        /// <param name="sheetName">Tên bảng hoặc sheet (tên sheet phải kết thúc bởi dấu $)</param>
        /// <param name="headerEnable">Có sử dụng dòng đầu tiên làm tiêu đề hay không</param>
        /// <returns></returns>
        public DataTable ReadData(string sheetName, bool headerEnable)
        {
            try
            {
                if (!sheetName.EndsWith("$"))
                    sheetName += "$";
                OleDbConnection cn = CreateConnection(headerEnable);
                OleDbCommand cmd = new OleDbCommand();
                OleDbDataAdapter da = new OleDbDataAdapter();
                DataTable dt = new DataTable();
                dt.TableName = sheetName;
                cmd.CommandText = string.Format("SELECT * FROM [{0}]", sheetName);
                cmd.Connection = cn;
                da.SelectCommand = cmd;
                cn.Open();
                da.Fill(dt);
                cn.Close();
                cn.Dispose();
                return dt;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// Đọc dữ liệu từ một vùng trong sheet
        /// </summary>
        /// <param name="fileName">Tên file</param>
        /// <param name="sheetName">Tên sheet</param>
        /// <param name="startCell">địa chỉ ô bắt đầu</param>
        /// <param name="endCell">Địa chỉ ô kết thúc</param>
        /// <param name="headerEnable">Có sử dụng dòng đầu tiên làm tiêu đề hay không</param>
        /// <returns></returns>
        public DataTable ReadData(string sheetName, string startCell, string endCell, bool headerEnable)
        {
            try
            {
                if (!sheetName.EndsWith("$"))
                    sheetName += "$";
                OleDbConnection cn = CreateConnection(headerEnable);
                OleDbCommand cmd = new OleDbCommand();
                OleDbDataAdapter da = new OleDbDataAdapter();
                DataTable dt = new DataTable();

                cmd.CommandText = string.Format("SELECT * FROM [{0}{1}:{2}]", sheetName, startCell, endCell);
                cmd.Connection = cn;
                da.SelectCommand = cmd;
                cn.Open();
                da.Fill(dt);
                cn.Close();
                cn.Dispose();
                return dt;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion
    }
}
